/*
 * MethodsPropPane.java
 *
 * Created on September 30, 2001, 4:10 PM
 *
 * Modification Log:
 * 1.00   30th Sep 2001   Tanmay   Original version.
 * 1.01   30th Jan 2002   Tanmay   Moved out toggle modify button to main screen.
 * 1.02   02nd Feb 2002   Tanmay   Moved over to new attributes dialog.
 * 1.03   23rd Mar 2002   Tanmay   Corrected search behavior where all searches after
 *                                   a failed search also failed till the table 
 *                                   selection was changed manually.
 *-----------------------------------------------------------------------------------------
 *       10th Sep 2003   Tanmay   Moved to SourceForge (http://classeditor.sourceforge.net)
 *-----------------------------------------------------------------------------------------
 */

package gui;

import classfile.ClassFile;
import classfile.MethodInfo;
import classfile.AccessFlags;
import classfile.attributes.Attributes;
import classfile.ConstantPoolInfo;
import classfile.Utils;
import gui.attributes.*;
import guihelper.*;

import java.awt.Component;
import javax.swing.*;
import javax.swing.table.TableColumn;

/**
 * Copyright (C) 2002-2003  Tanmay K. Mohapatra
 * <br>
 *
 * @author 	Tanmay K. Mohapatra
 * @version     1.03, 23rd March, 2002
 */
public class MethodsPropPane extends javax.swing.JPanel {
    
    private ClassFile   currClassFile;
    private int iPrevMethod;
    private boolean bEditable;
    
    /** Creates new form MethodsPropPane */
    public MethodsPropPane() {
        initComponents();
    }

    public void setModifyMode(boolean bEditableIn) {
        bEditable = bEditableIn;
        MethodTableModel thisModel = (MethodTableModel)tblMethodNames.getModel();
        thisModel.setEditable(bEditable);
        btnAddMethod.setEnabled(bEditable);
        btnRemoveMethod.setEnabled(bEditable);
    }

    void clear() {
        tblMethodNames.setModel(new MethodTableModel(null));
        lblNumMethodAttribs.setText("");
    }
    
    void refresh() {
        clear();
        if(null == currClassFile) return;
        
        TableColumn thisCol;
        MethodTableModel thisModel = new MethodTableModel(currClassFile);
        thisModel.setEditable(bEditable);
        tblMethodNames.setModel(thisModel);
        thisModel.setCellEditors(tblMethodNames);

        thisCol = tblMethodNames.getColumnModel().getColumn(0);
        thisCol.setPreferredWidth(30);
        thisCol.setMaxWidth(80);
        
        thisCol = tblMethodNames.getColumnModel().getColumn(1);
        thisCol.setPreferredWidth(200);
        thisCol.setMaxWidth(400);

        thisCol = tblMethodNames.getColumnModel().getColumn(2);
        thisCol.setPreferredWidth(300);
        thisCol.setMaxWidth(400);

        thisCol = tblMethodNames.getColumnModel().getColumn(3);
        thisCol.setPreferredWidth(300);
        thisCol.setMaxWidth(600);
                
        tblMethodNames.changeSelection(0, 1, false, false);
    }
    
    void setClassFile(ClassFile classFile) {
        currClassFile = classFile;
    }
    
    private void searchMethod() {
        if (null == currClassFile) return;
        String sSrchStr = txtMethodSearch.getText().trim();
        if (sSrchStr.length() <= 0) return;
        if(-1 == iPrevMethod) return;

        MethodTableModel tblModel = (MethodTableModel)tblMethodNames.getModel();
        int iPrevMethodNew = tblModel.nextIndex(iPrevMethod+1, sSrchStr);
        if(iPrevMethodNew >= 0) {
            iPrevMethod = iPrevMethodNew;
            tblMethodNames.changeSelection(iPrevMethod, 1, false, false);
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        java.awt.GridBagConstraints gridBagConstraints;

        jScrollPane1 = new javax.swing.JScrollPane();
        tblMethodNames = new javax.swing.JTable();
        tblMethodNames.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        ListSelectionModel tblSM = tblMethodNames.getSelectionModel();
        tblSM.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                tblMethodNamesValueChanged(evt);
            }
        });
        jPanel3 = new javax.swing.JPanel();
        jTextArea1 = new javax.swing.JTextArea();
        txtMethodSearch = new javax.swing.JTextField();
        btnMethodSearch = new javax.swing.JButton();
        panelAttribs = new javax.swing.JPanel();
        jLabel5 = new javax.swing.JLabel();
        lblNumMethodAttribs = new javax.swing.JLabel();
        btnShowMethodAttribs = new javax.swing.JButton();
        panelEdit = new javax.swing.JPanel();
        btnAddMethod = new javax.swing.JButton();
        btnRemoveMethod = new javax.swing.JButton();

        setLayout(new java.awt.GridBagLayout());

        tblMethodNames.setModel(new MethodTableModel(null));
        tblMethodNames.setShowHorizontalLines(false);
        jScrollPane1.setViewportView(tblMethodNames);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        add(jScrollPane1, gridBagConstraints);

        jPanel3.setLayout(new java.awt.GridBagLayout());

        jPanel3.setBorder(new javax.swing.border.TitledBorder("Search"));
        jTextArea1.setEditable(false);
        jTextArea1.setText("Enter search string below and press Find \nto search from the current position");
        jTextArea1.setBackground(new java.awt.Color(204, 204, 255));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanel3.add(jTextArea1, gridBagConstraints);

        txtMethodSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtMethodSearchActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanel3.add(txtMethodSearch, gridBagConstraints);

        btnMethodSearch.setText("Find/Find Next");
        btnMethodSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnMethodSearchActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        jPanel3.add(btnMethodSearch, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        add(jPanel3, gridBagConstraints);

        panelAttribs.setLayout(new java.awt.GridBagLayout());

        panelAttribs.setBorder(new javax.swing.border.TitledBorder("Method Attributes"));
        jLabel5.setText("Number of Attributes");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        panelAttribs.add(jLabel5, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        panelAttribs.add(lblNumMethodAttribs, gridBagConstraints);

        btnShowMethodAttribs.setText("Show/Edit");
        btnShowMethodAttribs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnShowMethodAttribsActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        panelAttribs.add(btnShowMethodAttribs, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.5;
        add(panelAttribs, gridBagConstraints);

        panelEdit.setLayout(new java.awt.GridBagLayout());

        panelEdit.setBorder(new javax.swing.border.TitledBorder("Edit"));
        btnAddMethod.setText("Add New");
        btnAddMethod.setEnabled(false);
        btnAddMethod.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddMethodActionPerformed(evt);
            }
        });

        panelEdit.add(btnAddMethod, new java.awt.GridBagConstraints());

        btnRemoveMethod.setText("Delete");
        btnRemoveMethod.setEnabled(false);
        btnRemoveMethod.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRemoveMethodActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        panelEdit.add(btnRemoveMethod, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.5;
        add(panelEdit, gridBagConstraints);

    }//GEN-END:initComponents

    private void btnShowMethodAttribsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnShowMethodAttribsActionPerformed
        if (null == currClassFile) return;
        if(-1 == iPrevMethod) return;
        MethodInfo currMethod = currClassFile.methods.getMethod(iPrevMethod);
        if(null == currMethod) return;
        Attributes methodAttribs = currMethod.attributes;
        if (null == methodAttribs)  return;
        
        AttributesDialog attribsDial = new AttributesDialog(AttributeTreeNode.getFrameFrom(this), true);
        attribsDial.setTitle("Method Attributes");
        attribsDial.setInput(methodAttribs, currClassFile.constantPool, bEditable);
        attribsDial.show();
    }//GEN-LAST:event_btnShowMethodAttribsActionPerformed
    
    private void btnRemoveMethodActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveMethodActionPerformed
        if (-1 != iPrevMethod) {
            // delete the prev fld
            MethodInfo thisMethod = currClassFile.methods.getMethod(iPrevMethod);
            String [] aParams = thisMethod.getMethodDesc();
            String sMethodStr = thisMethod.accessFlags.toString() + " " +
                aParams[0] + " " +
                thisMethod.getMethodName() + " (";
            for(int iParamIndex=1; iParamIndex < aParams.length; iParamIndex++) {
                sMethodStr += aParams[iParamIndex];
                if ((iParamIndex+1) < aParams.length) sMethodStr += ",";
            }
            sMethodStr += ")";
            
            int iConfirm = JOptionPane.showConfirmDialog(null,
                "Are you sure you want to delete the method\n" + sMethodStr + "?",
                "Confirm Delete", JOptionPane.YES_NO_OPTION);
            if(JOptionPane.YES_OPTION == iConfirm) {
                currClassFile.methods.deleteMethod(iPrevMethod);
                refresh();
            }
        }
    }//GEN-LAST:event_btnRemoveMethodActionPerformed
        
    private void btnAddMethodActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddMethodActionPerformed
        if (null == currClassFile) return;
        
        ((MethodTableModel)tblMethodNames.getModel()).addNewMethod();
        refresh();
        tblMethodNames.changeSelection(tblMethodNames.getModel().getRowCount()-1, 1, false, false);
    }//GEN-LAST:event_btnAddMethodActionPerformed
    
    private void tblMethodNamesValueChanged(javax.swing.event.ListSelectionEvent evt) {
        if(evt.getValueIsAdjusting()) return;
        if((null == currClassFile) || (null == currClassFile.methods) || 
           (currClassFile.methods.getMethodsCount() == 0)) {
            iPrevMethod = -1;
            return;
        }
        int iSelectedRow = tblMethodNames.getSelectedRow();
        if(0 > iSelectedRow) {
            iPrevMethod = -1;
            return;
        }
        
        iPrevMethod = iSelectedRow;
        MethodInfo thisMethod = currClassFile.methods.getMethod(iSelectedRow);
        lblNumMethodAttribs.setText(Integer.toString((null != thisMethod.attributes) ? thisMethod.attributes.getAttribCount() : 0));
    }
        
    private void txtMethodSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtMethodSearchActionPerformed
        searchMethod();
    }//GEN-LAST:event_txtMethodSearchActionPerformed
    
    private void btnMethodSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMethodSearchActionPerformed
        searchMethod();
    }//GEN-LAST:event_btnMethodSearchActionPerformed
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAddMethod;
    private javax.swing.JButton btnMethodSearch;
    private javax.swing.JButton btnRemoveMethod;
    private javax.swing.JButton btnShowMethodAttribs;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JLabel lblNumMethodAttribs;
    private javax.swing.JPanel panelAttribs;
    private javax.swing.JPanel panelEdit;
    private javax.swing.JTable tblMethodNames;
    private javax.swing.JTextField txtMethodSearch;
    // End of variables declaration//GEN-END:variables
    
}

